<template>
  <div class="todo-container">
    <div class="todo-wrap">
      <!--方式1. 给<TodoHeader>绑定监听  ---简单且直接(但只适用于父子组件之间)-->
      <!--<TodoHeader @addTodo="addTodo"/>--> <!--设置监听：给TodoHeader标签对象绑定addTodo事件监听；$emit : 触发事件-->
      <!--方式2. 给 <TodoHeader> 添加事件监听-->
      <TodoHeader ref="header"/>
      <!--方式3. 用PubSub给孙组件TodoItem.vue通信(优点：可以隔代通信)      -->
      <TodoList :todos="todos" />

      <!--方式4：适用于重复使用的页面   特性：这种通信是通过标签通信，上面三种通信是通过数据通信         -->
<!--      <todo-footer :todos="todos" :deleteCompleteTodos="deleteCompleteTodos" :selectAllTodos="selectAllTodos"/>-->
      <todo-footer>
        <input type="checkbox" v-model="isAllCheck" slot="checkAll"/>
        <span slot="count">已完成{{completeSize}} / 全部{{todos.length}} </span>
        <button slot="delete" class="btn btn-danger" v-show="completeSize" @click="deleteCompleteTodos">清除已完成任务</button>
      </todo-footer>

    </div>
  </div>
</template>


<!--
  绑定事件监听  ----   订阅消息
  触发事件    ------    发布消息
-->


<script>
  import Pubsub from 'pubsub-js'
  import TodoHeader from './components/TodoHeader.vue'
  import TodoList from './components/TodoList.vue'
  import TodoFooter from './components/TodoFooter.vue'
  import storageUtil from './util/storageUtil'

    export default {
        name: "App",
      data() {
        return {
          // todos: [
          //   {title: '吃饭', complete: false},
          //   {title: '睡觉', complete: true},
          //   {title: 'coding', complete: false}
          // ]
          // todos: JSON.parse(window.localStorage.getItem('todos_key') || '[]')
          todos: storageUtil.readTodos()
        }
      },
      //计算属性
      computed:{
        completeSize(){
          return this.todos.reduce((preTotal, todo) => preTotal + (todo.complete?1:0),0);
        },
        isAllCheck:{
          get(){
            return this.completeSize === this.todos.length && this.completeSize > 0;
          },
          set(value){   //value是当前checkbox的最新值：true/false
            this.selectAllTodos(value);
          }
        }
      },
      mounted() {   //执行异步代码
        //给<TodoHeader/>  绑定addTodo事件监听
        // this.$on('addTodo',this.addTodo);    //给App绑定的监听，不对
        this.$refs.header.$on('addTodo',this.addTodo);

        //订阅消息(优点：可以组孙组件传值，隔代)
        // 此时this为PubSub,所以会找不到deleteTodo
        // Pubsub.subscribe('deleteTodo',  function(msg, index) {
        Pubsub.subscribe('deleteTodo',  (msg, index) => {
          this.deleteTodo(index);
        });

      },
      components: {
        TodoHeader,
        TodoList,
        TodoFooter
      },
      methods: {
          addTodo(todo){
            this.todos.unshift(todo);
          },
          deleteTodo(index) {
            this.todos.splice(index,1);
          },

          //删除所有选中的todo
          deleteCompleteTodos(){
            //留下为complete值为false(未选中)的todo
            this.todos = this.todos.filter(todo => !todo.complete);
          },
          //全选 / 全不选
          selectAllTodos(check){
            this.todos.forEach(todo => todo.complete = check);
          }
      },
      watch:{   //监视
          todos: {
            deep: true,   //深度监视
            /*handler: function (value) {
                // 将todos最新的值的json数据，保存到localStorage
                window.localStorage.setItem('todos_key',JSON.stringify(value));
            }*/

              //handler: storageUtil.saveTodos(value);//1.
              handler: storageUtil.saveTodos    //2. 最低14k的写法，解析如下
              // handler: function (todos) {
              //   window.localStorage.setItem(TODOS_KEY,JSON.stringify(todos));
              // }

          }
      }
    }
</script>

<style scoped>
  .todo-container {
    width: 600px;
    margin: 0 auto;
  }
  .todo-container .todo-wrap {
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 5px;
  }
</style>
